export const STATUS_ADD = 'add' as const;
export const STATUS_KEEP = 'keep' as const;
export const STATUS_REMOVE = 'remove' as const;
export const STATUS_REMOVED = 'removed' as const;
export type DiffStatus =
  | typeof STATUS_ADD
  | typeof STATUS_KEEP
  | typeof STATUS_REMOVE
  | typeof STATUS_REMOVED;
import type { YmCssMotionListProps } from '../interface';

// export interface KeyObject {
//   key: React.Key;
//   status?: DiffStatus;
// }

// export function wrapKeyToObject(key: React.Key | KeyObject) {
//   let keyObj: KeyObject;
//   if (key && typeof key === 'object' && 'key' in key) {
//     keyObj = key;
//   } else {
//     keyObj = { key: key as React.Key };
//   }
//   return {
//     ...keyObj,
//     key: String(keyObj.key),
//   };
// }

// export function parseKeys(keys = []) {
//   return keys.map(wrapKeyToObject);
// }

type DataSource = YmCssMotionListProps['dataSource'];

export function diffDataSource(
  prevDataSource: DataSource,
  currDataSource: DataSource,
  rowKey: string,
) {
  let list: { status: DiffStatus; [property: string]: any }[] = [];
  //举例：add  prevKeys = [1,2] currentkeys = [1,3,2];
  //       prevKeys = [1,2] currentkeys = [1,2,3];

  //   remove prevKeys = [1,2] currentkeys = [1];
  // [1,2,3] -- [1,2] 尾删
  // [1,2,3] -- [2,3] 头删
  // [1,2,3] -- [1,3] 中间删

  //    add               [1,2,3] -- [1,2,3,4] 尾加
  //[1,2,3] -- [4,1,2,3] 头加
  //[1,2,3] -- [1,2,4,3] 中间加

  // [1,2,3] -- [3,1,2,4] 下面就满足不了了

  // 先remove再add        [1,2,3] -- [1,4,3]
  // 先add 再 remove      [1,2,3] -- [4]
  //   move   prevKeys = [1,2] currentkeys = [2,1]; 排序不会有动画

  //方案最终确定： 外层循环currentkeys，currentkeys中没有的,prevKeys有的(有删除)就根据在prevKeys中的index 插入到currentkeys中

  const needRemoveList = prevDataSource.reduce(
    (
      prev: Record<string, any>[],
      prevObj: any,
      prevIndex: number,
      prevArray: DataSource,
    ) => {
      const existCurrKeyIndex = currDataSource.findIndex(
        (currObj) =>
          currObj[rowKey] !== undefined &&
          currObj[rowKey] !== null &&
          prevObj[rowKey] !== undefined &&
          prevObj[rowKey] !== null &&
          currObj[rowKey] === prevObj[rowKey],
      );
      if (existCurrKeyIndex < 0) {
        // prev[prevObj[rowKey]] = {...prevObj,prevIndex};
        prev.push({ ...prevObj, inserIndex: prevIndex });
      }
      return prev;
    },
    [],
  );

  currDataSource.forEach((currObj) => {
    const existPrevKeyIndex = prevDataSource.findIndex(
      (prevObj) =>
        currObj[rowKey] !== undefined &&
        currObj[rowKey] !== null &&
        prevObj[rowKey] !== undefined &&
        prevObj[rowKey] !== null &&
        currObj[rowKey] === prevObj[rowKey],
    );
    let currStatus;
    if (existPrevKeyIndex > -1) {
      currStatus = STATUS_KEEP;
    } else {
      currStatus = STATUS_ADD;
    }
    list.push({ ...currObj, status: currStatus });
  });

  if (needRemoveList.length > 0) {
    needRemoveList.forEach((needRemoveItem) => {
      const { inserIndex, ...restParams } = needRemoveItem;
      if (inserIndex >= currDataSource.length) {
        list.push({ ...restParams, status: STATUS_REMOVE });
      } else {
        const firstParts = list.slice(0, inserIndex); //slice >=, <
        const secondParts = list.slice(inserIndex);
        list = [
          ...firstParts,
          { ...restParams, status: STATUS_REMOVE },
          ...secondParts,
        ];
      }
    });
  }

  return list;
}
